/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/math
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AEEulerUtil.h
// Author:		Gianluca Belardelli
// Date:		31/07/2013
// Purpose:		Dichiarazione della classe AEEulerUtil
//
// Revision:
//				001 - 31/07/2013
//					+ Revisione iniziale
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AEEULERUTIL_H_
#define _AEEULERUTIL_H_

#include <core/math/AEMath.h>
#include <core/math/AEEulerMode.h>

/// \brief
///   This is a helper class to convert Euler angles to and from matrices and quaternions.
///   It works with every mode known to man.
///   The code was taken from "Graphics Gems IV", "Euler Angle Conversion" by Ken Shoemake, page 222.
class AEEulerUtil
{
public:

  ///
  /// @name Euler Angles to Rotation Matrices
  /// @{
  ///

  /// \brief Creates a AEMatrix3 rotation matrix from Euler Angles which are given in radians.
  static AEMatrix3 ConvertEulerToMat3_Rad( float fRotation1, float fRotation2, float fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  /// \brief Creates a AEMatrix3 rotation matrix from Euler Angles which are given in degree.
  AE_FORCEINLINE static AEMatrix3 ConvertEulerToMat3_Deg( float fRotation1, float fRotation2, float fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );


  /// \brief Creates a AEMatrix4 rotation matrix from Euler Angles which are given in radians.
  AE_FORCEINLINE static AEMatrix4 ConvertEulerToMat4_Rad( float fRotation1, float fRotation2, float fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  /// \brief Creates a AEMatrix4 rotation matrix from Euler Angles which are given in degree.
  AE_FORCEINLINE static AEMatrix4 ConvertEulerToMat4_Deg( float fRotation1, float fRotation2, float fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  ///
  /// @}
  ///

  ///
  /// @name Euler Angles to Quaternions
  /// @{
  ///

  /// \brief Creates a AEQuaternion from Euler Angles which are given in radians.
  static AEQuaternion ConvertEulerToQuaternion_Rad( float fRotation1, float fRotation2, float fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  /// \brief Creates a AEQuaternion from Euler Angles which are given in degree.
  AE_FORCEINLINE static AEQuaternion ConvertEulerToQuaternion_Deg( float fRotation1, float fRotation2, float fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  ///
  /// @}
  ///

  ///
  /// @name Rotation Matrices to Euler Angles
  /// @{
  ///

  /// \brief Extracts Euler Angles from a AEMatrix3 and returns them in radians.
  static void ConvertMat3ToEuler_Rad( const AEMatrix3 &matIn, float &fRotation1, float &fRotation2, float &fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  /// \brief Extracts Euler Angles from a AEMatrix3 and returns them in degree.
  AE_FORCEINLINE static void ConvertMat3ToEuler_Deg( const AEMatrix3 &matIn, float &fRotation1, float &fRotation2, float &fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  /// \brief Extracts Euler Angles from a AEMatrix4 and returns them in radians.
  AE_FORCEINLINE static void ConvertMat4ToEuler_Rad( const AEMatrix4 &matIn, float &fRotation1, float &fRotation2, float &fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  /// \brief Extracts Euler Angles from a AEMatrix4 and returns them in degree.
  AE_FORCEINLINE static void ConvertMat4ToEuler_Deg( const AEMatrix4 &matIn, float &fRotation1, float &fRotation2, float &fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  ///
  /// @}
  ///

  ///
  /// @name Quaternions to Euler Angles
  /// @{
  ///

    /// \brief Extracts Euler Angles from a AEQuaternion and returns them in radians.
  static void ConvertQuaternionToEuler_Rad( const AEQuaternion &qtIn, float &fRotation1, float &fRotation2, float &fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  /// \brief Extracts Euler Angles from a AEQuaternion and returns them in degree.
  AE_FORCEINLINE static void ConvertQuaternionToEuler_Deg( const AEQuaternion &qtIn, float &fRotation1, float &fRotation2, float &fRotation3, AEEulerMode::Enum EulerMode = AEEulerMode::AEEngineDefault );

  ///
  /// @}
  ///
};

#include <core/math/utils/AEEulerUtil.inl>

#endif
// _AEEULERUTIL_H_
